/** * Copyright (c) Codice Foundation * * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. * **/ package org.codice.ddf.spatial.ogc.wfs.catalog.endpoint.writer; import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.ws.rs.WebApplicationException; import javax.xml.XMLConstants; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.apache.commons.io.IOUtils; import org.apache.xerces.dom.DOMInputImpl; import org.codice.ddf.spatial.ogc.wfs.catalog.common.WfsFeatureCollection; import org.custommonkey.xmlunit.XMLUnit; import org.junit.Test; import org.w3c.dom.ls.LSInput; import org.w3c.dom.ls.LSResourceResolver; import org.xml.sax.SAXException; import ddf.catalog.data.AttributeDescriptor; import ddf.catalog.data.Metacard; import ddf.catalog.data.impl.AttributeDescriptorImpl; import ddf.catalog.data.impl.BasicTypes; import ddf.catalog.data.impl.MetacardImpl; import ddf.catalog.data.impl.MetacardTypeImpl; public class TestFeatureCollectionMessageBodyWriter { private static final String SOURCE = "src"; private static final String CONTENT_TYPE = "Sport"; private static final String CONTENT_TYPE_VERSION = "1.0.0"; private static final Date DATE = new Date(1364320829000L); private static final String ID = "team_id"; private static final String TITLE = "team_name"; private static final String HOME_LOCATION = "home"; private static final String AWAY_LOCATION = "away"; private static final String WINS = "wins"; private static final String DATE_CREATED = "date_created"; private static final String TEAM1_ID = "team1"; private static final String TEAM2_ID = "team2"; private static final String TEAM1_LOCATION = "POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))"; private static final String TEAM2_LOCATION = "POLYGON ((1 1, 2 2, 3 3, 4 4, 1 1))"; private static final int WIN_COUNT = 55; private static final String BASIC_ID = "basic_id"; private static final String BASIC_CONTENT_TYPE = "basic"; private static final String BASIC_TITLE = "basic_title"; private static final String BASIC_LOCATION = "POINT(1 1)"; @Test public void testWriteToGeneratesGMLConformantXml() throws IOException, WebApplicationException, SAXException { FeatureCollectionMessageBodyWriter wtr = new FeatureCollectionMessageBodyWriter(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); wtr.writeTo(getWfsFeatureCollection(), null, null, null, null, null, stream); String actual = stream.toString(); SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); schemaFactory.setResourceResolver(new LSResourceResolver() { private Map<String, String> schemaLocations; private Map<String, LSInput> inputs; { inputs = new HashMap<String, LSInput>(); schemaLocations = new HashMap<String, String>(); schemaLocations.put("xml.xsd", "/w3/1999/xml.xsd"); schemaLocations.put("xlink.xsd", "/w3/1999/xlink.xsd"); schemaLocations.put("geometry.xsd", "/gml/2.1.2/geometry.xsd"); schemaLocations.put("feature.xsd", "/gml/2.1.2/feature.xsd"); schemaLocations.put("gml.xsd", "/gml/2.1.2/gml.xsd"); schemaLocations.put("expr.xsd", "/filter/1.0.0/expr.xsd"); schemaLocations.put("filter.xsd", "/filter/1.0.0/filter.xsd"); schemaLocations .put("filterCapabilities.xsd", "/filter/1.0.0/filterCapabilties.xsd"); schemaLocations.put("WFS-capabilities.xsd", "/wfs/1.0.0/WFS-capabilities.xsd"); schemaLocations.put("OGC-exception.xsd", "/wfs/1.0.0/OGC-exception.xsd"); schemaLocations.put("WFS-basic.xsd", "/wfs/1.0.0/WFS-basic.xsd"); schemaLocations.put("WFS-transaction.xsd", "/wfs/1.0.0/WFS-transaction.xsd"); schemaLocations.put("wfs.xsd", "/wfs/1.0.0/wfs.xsd"); } @Override public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { String fileName = new java.io.File(systemId).getName(); if (inputs.containsKey(fileName)) { return inputs.get(fileName); } LSInput input = new DOMInputImpl(); InputStream is = getClass().getResourceAsStream(schemaLocations.get(fileName)); input.setByteStream(is); input.setBaseURI(baseURI); input.setSystemId(systemId); inputs.put(fileName, input); return input; } }); Source wfsSchemaSource = new StreamSource( getClass().getResourceAsStream("/wfs/1.0.0/wfs.xsd")); Source testSchemaSource = new StreamSource(getClass().getResourceAsStream("/schema.xsd")); Schema schema = schemaFactory.newSchema(new Source[] {wfsSchemaSource, testSchemaSource}); try { schema.newValidator().validate(new StreamSource(new StringReader(actual))); } catch (Exception e) { fail("Generated GML Response does not conform to WFS Schema" + e.getMessage()); } } @Test public void testWriteToGeneratesExpectedNonBasicMetacard() throws IOException, WebApplicationException, SAXException { FeatureCollectionMessageBodyWriter wtr = new FeatureCollectionMessageBodyWriter(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); wtr.writeTo(getWfsFeatureCollection(), null, null, null, null, null, stream); String actual = stream.toString(); String expected = IOUtils.toString(getClass().getResourceAsStream("/wfs.xml"), "UTF-8"); XMLUnit.setIgnoreWhitespace(true); assertXMLEqual("Failed to generate correct GML", expected, actual); } @Test public void testWriteToGeneratesExpectedBasicMetacard() throws IOException, WebApplicationException, SAXException { FeatureCollectionMessageBodyWriter wtr = new FeatureCollectionMessageBodyWriter(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); wtr.writeTo(getBasicWfsFeatureCollection(), null, null, null, null, null, stream); String actual = stream.toString(); String expected = IOUtils.toString(getClass().getResourceAsStream("/basic.xml"), "UTF-8"); XMLUnit.setIgnoreWhitespace(true); assertXMLEqual("Failed to generate correct GML", expected, actual); } private WfsFeatureCollection getWfsFeatureCollection() { WfsFeatureCollection collection = new WfsFeatureCollection(); List<Metacard> metacards = new ArrayList<Metacard>(); metacards.add(getMetacard(TEAM1_ID, TEAM1_LOCATION, TEAM2_LOCATION)); metacards.add(getMetacard(TEAM2_ID, TEAM2_LOCATION, TEAM1_LOCATION)); collection.setFeatureMembers(metacards); return collection; } private WfsFeatureCollection getBasicWfsFeatureCollection() { WfsFeatureCollection collection = new WfsFeatureCollection(); List<Metacard> metacards = new ArrayList<Metacard>(); metacards.add(getBasicMetacard()); collection.setFeatureMembers(metacards); return collection; } private Metacard getMetacard(String team, String home, String away) { Set<AttributeDescriptor> descriptors = new HashSet<AttributeDescriptor>(); descriptors.addAll(BasicTypes.BASIC_METACARD.getAttributeDescriptors()); descriptors.add(new AttributeDescriptorImpl(ID, false, false, false, false, BasicTypes.LONG_TYPE)); descriptors.add(new AttributeDescriptorImpl(TITLE, false, false, false, false, BasicTypes.STRING_TYPE)); descriptors.add(new AttributeDescriptorImpl(DATE_CREATED, false, false, false, false, BasicTypes.DATE_TYPE)); descriptors.add(new AttributeDescriptorImpl(WINS, false, false, false, false, BasicTypes.INTEGER_TYPE)); descriptors.add(new AttributeDescriptorImpl(HOME_LOCATION, false, false, false, false, BasicTypes.GEO_TYPE)); descriptors.add(new AttributeDescriptorImpl(AWAY_LOCATION, false, false, false, false, BasicTypes.GEO_TYPE)); MetacardTypeImpl metacardType = new MetacardTypeImpl(CONTENT_TYPE, descriptors); MetacardImpl metacard = new MetacardImpl(); metacard.setType(metacardType); metacard.setContentTypeName(CONTENT_TYPE); metacard.setContentTypeVersion(CONTENT_TYPE_VERSION); metacard.setCreatedDate(DATE); metacard.setEffectiveDate(DATE); metacard.setId(team); metacard.setLocation(home); metacard.setSourceId(SOURCE); metacard.setTitle(team); metacard.setAttribute(ID, team); metacard.setAttribute(TITLE, team); metacard.setAttribute(DATE_CREATED, DATE); metacard.setAttribute(WINS, WIN_COUNT); metacard.setAttribute(HOME_LOCATION, home); metacard.setAttribute(AWAY_LOCATION, away); return metacard; } private Metacard getBasicMetacard() { MetacardImpl metacard = new MetacardImpl(); metacard.setType(BasicTypes.BASIC_METACARD); metacard.setContentTypeName(BASIC_CONTENT_TYPE); metacard.setContentTypeVersion(CONTENT_TYPE_VERSION); metacard.setCreatedDate(DATE); metacard.setEffectiveDate(DATE); metacard.setId(BASIC_ID); metacard.setLocation(BASIC_LOCATION); metacard.setSourceId(SOURCE); metacard.setTitle(BASIC_TITLE); return metacard; } }